"""
XML-RPC Lucene Server adapter
"""

import gc
import PyLucene
import threading
import base64

from twisted.web import xmlrpc
from nokcene.xmlquery import XMLQuery
from nokcene.xmlquery_new import XMLSearchQuery
from nokcene.threadpool__ import ThreadPool

class XMLRPCServer(xmlrpc.XMLRPC) :
	"""Lucene XML-RPC server """

	def __init__(self, core, write_pool_size=10) :
		#super(XMLRPCServer, self).__init__()
		xmlrpc.XMLRPC.__init__(self)
		assert (core is not None)
		self._core = core

		# Thread write pool
		self._write_sync = False
		self._write_pool = None
		self._write_pool_size = write_pool_size

	def _getWriteThreadPool(self) :
		if not self._write_sync:
			if self._write_pool is None:
				self._write_pool = ThreadPool(self._write_pool_size)
		return self._write_pool

	def xmlrpc_indexDocument(self, uid, xml_query="", b64=False, sync=False) :
		#self._core.log.debug( \
		#	"xmlrpc_indexDocument gc.garbage : %s" % str(gc.garbage))

		args = (uid, xml_query, b64)
		pool = self._getWriteThreadPool()
		if sync is False and pool is not None :
			pool.queueTask(self._indexDocument, args, None)
		else:
			self._indexDocument(*args)

		gc.collect()
		return True

	def xmlrpc_reindexDocument(self, uid, xml_query="", b64=False, sync=False) :
		return self.xmlrpc_indexDocument(uid, xml_query, b64, sync)

	def xmlrpc_unindexDocument(self, uid, sync=False) :
		args = (uid,)
		pool = self._getWriteThreadPool()
		if sync is False and pool is not None:
			pool.queueTask(
				self._unindexDocument, (uid,), None)
		else:
			self._unindexDocument(*args)
		gc.collect()
		return True

	def xmlrpc_search(self, query_str="") :
		#self._core.log.debug("xmlrpc_indexDocument gc.garbage : %s" % str(gc.garbage))

		# XXX not tested yet.
		if not query_str :
			return list()
		else :
			return self._core.search(query_str)

	def xmlrpc_searchQuery(self, xml_query="") :
		if not xml_query:
			return str()
		else :
			self._core.log.info("xmlrpc_searchQuery....")
			iquery = XMLSearchQuery(xml_query)

			params = (
				iquery.getReturnFields(),
				iquery.getSearchFields(),
				iquery.getSearchOptions(),
				)

			self._core.log.debug(
				"xmlrpc_searchQuery : search_fields=%s "
				"search_options=%s and search_options=%s" % params )

			res = self._core.searchQuery(*params)
			gc.collect()
			return res

	def xmlrpc_hasUID(self, uid) :
		return self._core.getDocumentByUID(uid) is not None

	def xmlrpc_clean(self) :
		self._core.clean()
		return True

	def xmlrpc_getStoreDir(self) :
		return self._core.store_dir

	def xmlrpc_optimize(self) :
		self._core.optimize()
		return True

	def xmlrpc_getNumberOfDocuments(self) :
		return len(self._core)

	def xmlrpc_debug(self, msg) :
		return msg

	#
	# Private API
	#

	def _indexDocument(self, uid, xml_query="", b64=False) :
		self._core.log.info("xmlrpc_indexDocument: uid=%s " % str(uid))

		try :
			if xml_query:
				if b64 is True:
					xml_query = base64.b64decode(xml_query)
				iquery = XMLQuery(xml_query)
				res = self._core.indexDocument(uid, iquery)
				return res
			return False
		except Exception, e :
			print e
			return False

	def _unindexDocument(self, uid) :
		self._core.log.info("xmlrpc_unindexob : uid=%s" % str(uid))
		res = self._core.unindexDocument(uid)
		return res

